package com.fanshuai.spring.boot;

import com.fanshuai.spring.boot.local.domain.User;
import com.fanshuai.spring.boot.local.jdbc.NativeTxService;
import com.fanshuai.spring.boot.local.mybatisplus.service.MybatisPlusUserService;
import com.fanshuai.spring.boot.local.spring.service.UserService;
import com.fanshuai.spring.boot.sql.StatementCreator;
import com.fanshuai.spring.boot.xa.jta.AtomikosXAService;
import com.fanshuai.spring.boot.xa.mysql.CustomXAService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;

@Service
public class MainService {
    @Resource
    private CustomXAService customXAService;
    @Resource
    private AtomikosXAService atomikosXAService;
    @Resource
    private UserService userService;
    @Resource
    private MybatisPlusUserService mybatisPlusUserService;
    @Resource
    private NativeTxService nativeTxService;

    private List<User> get() {
        List<User> userList = new ArrayList<>();
        userList.add(new User(0, "fanshuai"));
        userList.add(new User(0, "fanshuai2"));
        userList.add(new User(0, "fanshuai3"));
        userList.add(new User(0, "fanshuai4"));
        return userList;
    }

    public void nativeJdbc() {
        List<User> userList = get();
        nativeTxService.batchAdd(userList);
    }

    public void localJdbc() {
        List<User> userList = get();
        userService.batchAdd(userList);
        userService.batchAdd2(userList);
    }

    public void localMybatisPlus() {
        List<User> userList = get();
        mybatisPlusUserService.batchAdd(userList);
        mybatisPlusUserService.batchAdd2(userList);
    }

    public void xa() {
        List<User> userList = get();
        StatementCreator creator1 = connection -> {
            List<PreparedStatement> statements = new ArrayList<>();
            for (User user : userList) {
                try {
                    PreparedStatement statement = connection.prepareStatement("insert into user(name) values (?)");
                    statement.setString(1, user.getName());
                    statements.add(statement);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
            return statements;
        };
        StatementCreator creator2 = connection -> {
            List<PreparedStatement> statements = new ArrayList<>();
            for (User user : userList) {
                try {
                    PreparedStatement statement = connection.prepareStatement("insert into user(name) values (?)");
                    statement.setString(1, user.getName());
                    statements.add(statement);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
            return statements;
        };

        customXAService.executeXA(creator1, creator2);
    }

    public void jta() throws Exception {
        List<User> userList = get();
        StatementCreator creator1 = connection -> {
            List<PreparedStatement> statements = new ArrayList<>();
            for (User user : userList) {
                try {
                    PreparedStatement statement = connection.prepareStatement("insert into user(name) values (?)");
                    statement.setString(1, user.getName());
                    statements.add(statement);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
            return statements;
        };
        StatementCreator creator2 = connection -> {
            List<PreparedStatement> statements = new ArrayList<>();
            for (User user : userList) {
                try {
                    PreparedStatement statement = connection.prepareStatement("insert into user(name) values (?)");
                    statement.setString(1, user.getName());
                    statements.add(statement);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
            return statements;
        };
        atomikosXAService.executeJta(creator1, creator2);
    }

    public void jtaSpringTemplate() {
        List<User> userList = get();
        atomikosXAService.executeJtaTemplate(userList);
    }

    public void jtaJtaTransactionManager() {
        List<User> userList = get();
        atomikosXAService.executeJtaTransactionManager(userList);
    }
}
